from django.db import transaction
from rest_framework import serializers
from goods.models import SKU,GoodsCategory,SPUSpecification,SpecificationOption,SKUSpecification

#0.SKUSpecification序列化器,重写成前端需要的字段
class SKUSpecificationSerializer(serializers.Serializer):
    spec_id=serializers.IntegerField()
    option_id=serializers.IntegerField()

#1商品列表序列化器
class SKUVieSetSerializers(serializers.ModelSerializer):
    # 1,重写分类,使之显示对应分类名字而不是外键id,字段类型与请求的不一致,所以要重写
    category=serializers.StringRelatedField(read_only=True)
    spu=serializers.StringRelatedField(read_only=True)

    # 2,请求的字段,原模型没有所以曹重写自定义添加
    category_id=serializers.IntegerField()
    spu_id=serializers.IntegerField()

    ##3,specs重写重写成前端需要的字段
    specs=SKUSpecificationSerializer(read_only=True,many=True)


    class Meta:
            model=SKU
            fields="__all__"

     #3.因为ModelSerializer的create方法无法保存新增商品规格,所以要重写create方法

    # 3,重写create方法,保存sku和对应的规格
    #在添加sku的时候,保证和对应的spec的规格同时成功或者失败,添加事物
    @transaction.atomic
    def create(self, validated_data):
        # TODO 设置保存点
        sid = transaction.savepoint()
        try:
             # 1,创建sku对象
            sku=SKU.objects.create(**validated_data)

            # 2,创建规格信息入库,context["request"].data["specs"]是debug那里获取的,具体方法看day22 视频3
            specs = self.context["request"].data["specs"]
            for specs_dict in specs:
                SKUSpecification.objects.create(sku_id=sku.id,spec_id=specs_dict["spec_id"],option_id=specs_dict["option_id"])
        except Exception:
            transaction.savepoint_rollback(sid) #TODO 回滚
            raise serializers.ValidationError("保存失败")
        else:
            # 3,返回响应,
            transaction.savepoint_commit(sid)  # TODO 提交
            return  sku

            # 4,重写update方法,更新sku中的规格
    @transaction.atomic
    def update(self, instance, validated_data):

        # TODO 设置保存点
        sid = transaction.savepoint()

        try:
            # 1,更新sku其他信息(标题,价格,...)
            SKU.objects.filter(id=instance.id).update(**validated_data)

            # 1,1 删除以前所有的规格
            [spec.delete() for  spec in instance.specs.all()]

            # 2,更新规格信息入库
            specs = self.context["request"].data["specs"]
            for spec_dict in specs:
                SKUSpecification.objects.filter(sku_id=instance.id, spec_id=spec_dict['spec_id']).update(
                    option_id=spec_dict["option_id"])
        except Exception as e:
            transaction.savepoint_rollback(sid)  # TODO 回滚
            raise serializers.ValidationError("保存失败")
        else:

            # 3,返回响应,
            transaction.savepoint_commit(sid)  # TODO 提交
            return SKU.objects.get(id=instance.id)

#2.sku商品分类序列化器
class SKUCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model=GoodsCategory
        fields=("id","name")

#3.spu商品分类序列化器
class SKUGoodSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model=SKU
        fields=("id","name")

#4新增产品规格选项序列化
class SpecificationOptionSerializers(serializers.ModelSerializer):
    class Meta:
        model=SpecificationOption
        fields=("id","value")

#4.1新增商品spu规格显示
class SPUSpecificationerializers(serializers.ModelSerializer):
    # #重写与请求不同的或没有的字段
    spu=serializers.StringRelatedField(read_only=True)
    spu_id=serializers.IntegerField()
    # 2,前端还需要重写options,options里边是规格选项,有规格名和规格id,所以要将规格选项表进行序列化,再取SpecificationOptionSerializer里边的量选项
    options=SpecificationOptionSerializers(read_only=True,many=True)
    class Meta:
        model=SPUSpecification
        fields="__all__"